package com.wsoft.bpm.component;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.wsoft.bpm.bean.ApprovalChainNode;
import com.wsoft.bpm.bean.DynamicApprovalChain;
import com.wsoft.bpm.constants.BpmConstant;
import com.wsoft.bpm.enums.ActivityVariable;
import com.wsoft.bpm.service.impl.ChainWorkFlowService;
import com.wsoft.bpm.utils.ActivityUtils;
import lombok.extern.log4j.Log4j2;
import org.activiti.engine.TaskService;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.DelegateTask;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;

/**
 * 简单表达式函数实体类
 *
 * @Author zhonglj
 * @Date 2024-09-23 15:43
 */
@Log4j2
@Component("expressionListenerBean")
public class ExpressionListenerBean {
    public Collection<String> getSignCollection(DelegateExecution execution, String signCollectKey, String signCollectValue, String signCollectExpression) {
        Collection cacheCollection = execution.getVariable(signCollectKey, Collection.class);
        if (cacheCollection != null) {
            return cacheCollection;
        }
        Collection<String> signCollection = CollUtil.newArrayList();
        if (StrUtil.isNotBlank(signCollectValue)) {
            // 会签选择人
            signCollection = CollUtil.addAll(signCollection, StrUtil.split(signCollectValue, ","));
        }

        if (StrUtil.isNotBlank(signCollectExpression)) {
            // 会签表达式
            Object result = ActivityUtils.calculateExpression(signCollectExpression, execution);
            if (result != null) {
                if (result instanceof Collection) {
                    signCollection = CollUtil.addAll(signCollection, result);
                } else if (result instanceof String) {
                    signCollection = CollUtil.addAll(signCollection, StrUtil.split(result.toString(), ","));
                }
            }
        }
        // 初始化会签结果流程变量
        String currentActivityId = execution.getCurrentActivityId();
        execution.setVariable(ActivityVariable.SIGN_AGREE_COUNT_KEY.getValue() + currentActivityId, 0);
        execution.setVariable(ActivityVariable.SIGN_REFUSE_COUNT_KEY.getValue() + currentActivityId, 0);
        execution.setVariable(ActivityVariable.SIGN_COMPLETED_COUNT_KEY.getValue() + currentActivityId, 0);
        execution.setVariable(ActivityVariable.SIGN_ALL_COUNT_KEY.getValue() + currentActivityId, signCollection.size());

        // 防止多次调用collection影响计数
        execution.setVariable(signCollectKey, signCollection);
        return signCollection;
    }

    @Resource
    private TaskService taskService;

    /**
     * 在用户任务级别设置本地流程变量
     *
     * @param delegateTask
     * @param key
     * @param value
     * @return void
     * @author zhonglj
     * @date 2025/2/13 14:28
     **/
    public void setTaskLocalVariable(DelegateTask delegateTask, String key, Object value) {
        if (StrUtil.isNotBlank(key) && value != null) {
            taskService.setVariableLocal(delegateTask.getId(), key, value);
        }
    }

    @Resource
    private ChainWorkFlowService chainWorkFlowService;
    @Resource
    private AsyncTaskPoller asyncTaskPoller;

    /**
     * 创建动态审批链
     *
     * @param delegateTask 当前任务
     * @param variableKey  动态审批链key
     * @return void
     * @author zhonglj
     * @date 2025/2/13 14:29
     **/
    public void createDynamicApprovalChain(DelegateTask delegateTask, String variableKey) {
        if (StrUtil.isNotBlank(variableKey)) {
            // 获取用户自定义的动态审批链
            DynamicApprovalChain chain = taskService.getVariable(delegateTask.getId(), variableKey, DynamicApprovalChain.class);
            if (chain != null) {
                // 保存当前节点对应的动态审批链key值
                taskService.setVariableLocal(delegateTask.getId(), BpmConstant.Hr.VARIABLE_KEY_DYNAMIC_APPROVAL_CHAIN_KEY, variableKey);
                // 自动生成第一个并行审批节点
                if (chain.hasNextNode()) {
                    ApprovalChainNode approvalChainNode = chain.nextNode();
                    // 手动更新动态审批链路
                    taskService.setVariable(delegateTask.getId(), variableKey, chain);
                    // 动态创建子任务
                    String taskId = delegateTask.getId();
                    List<String> assignList = approvalChainNode.getAssignList();
                    String approvalName = approvalChainNode.getApprovalName();

                    asyncTaskPoller.executeWithCondition(
                            // 用户任务数据已入库
                            () -> taskService.createTaskQuery().taskId(taskId).singleResult() != null,
                            10 * 1000,
                            1000,
                            () -> {
                                // 创建动态审批节点
                                chainWorkFlowService.addDynamicChainNode(taskId, taskId, assignList, approvalName);
                            });
                } else {
                    log.error("初始化创建动态审批链失败!");
                }
            }
        }
    }
}
